package com.ruijie.acl.web;

import java.util.ArrayList;
import java.util.List;

import javax.faces.model.SelectItem;

import org.jboss.seam.ScopeType;
import org.jboss.seam.annotations.In;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Scope;
import org.jboss.seam.annotations.Transactional;
import org.jboss.seam.jsf.ListDataModel;

import com.ruijie.acl.AccessGroup;
import com.ruijie.acl.Ace;
import com.ruijie.acl.Template;
import com.ruijie.acl.TimeRange;
import com.ruijie.acl.service.AccessGroupService;
import com.ruijie.acl.service.AceService;
import com.ruijie.acl.service.DeviceAccessGroupService;
import com.ruijie.acl.type.MoveDirection;
import com.ruijie.acl.type.PortTypeEnum;
import com.ruijie.acl.type.ProtocolTypeEnum;
import com.ruijie.foundation.bo.EntityObject;
import com.ruijie.foundation.exception.BusinessException;
import com.ruijie.foundation.service.Repository;
import com.ruijie.acl.utils.AclUtil;

@Name("aceContrastAction")
@Scope(ScopeType.CONVERSATION)
public class AceContrastAction extends AclBaseAction {
	@In("#{aceService}")
	private AceService aceService;
	@In("#{accessGroupService}")
	private AccessGroupService accessGroupService;
	@In("#{deviceAccessGroupService}")
	private DeviceAccessGroupService deviceAccessGroupService;
	@In("#{accessGroupAction}")
	private AccessGroupAction accessGroupAction;
	private Ace model;
	private Ace criteria = new Ace();
	private boolean allowPaged = true;
	private boolean showParticular = false;
	private ListDataModel entityModelList = null;
	private EntityObject paramObject = null;
	private String paramType = "";
	private String aceOrder = "";
	private Integer aceCount = 0;
	private String timeRangeName = null;
	private String sourcePort = "";
	private String desPort = "";

	public String getSourcePort() {
		return sourcePort;
	}

	public void setSourcePort(String sourcePort) {
		this.sourcePort = sourcePort;
	}

	public String getDesPort() {
		return desPort;
	}

	public void setDesPort(String desPort) {
		this.desPort = desPort;
	}

	public String getTimeRangeName() {
		return timeRangeName;
	}

	public void setTimeRangeName(String timeRangeName) {
		this.timeRangeName = timeRangeName;
	}

	public String getAceOrder() {
		return aceOrder;
	}

	public void setAceOrder(String aceOrder) {
		this.aceOrder = aceOrder;
	}

	public String getParamType() {
		return paramType;
	}

	public void setParamType(String paramType) {
		this.paramType = paramType;
	}

	@SuppressWarnings("unchecked")
	@Override
	protected Repository getRepository() {
		return aceService;
	}

	@Override
	protected String getAddPage() {
		if (this.paramType == "Template") {
			return "/acl/aclTemplate/aceAdd4Template.seam";
		}
		return "/acl/aceAdd.seam";
	}

	@Override
	public EntityObject getCriteria() {
		return this.criteria;
	}

	@Override
	protected String getDetailPage() {
		if (this.paramType == "Template") {
			return "/acl/aclTemplate/aceDetail4Template.seam";
		}
		return "/acl/aceDetail.seam";
	}

	@Override
	protected String getListPage() {
		return "/acl/aceDetail.seam";
	}

	@Override
	public EntityObject getModel() {
		return this.model;
	}

	@Override
	protected String getUpdatePage() {
		if (this.paramType == "Template") {
			return "/acl/aclTemplate/aceEdit4Template.seam";
		}
		return "/acl/aceEdit.seam";
	}

	@Override
	protected String getToPageAfterAdd() {
		page = 1;
		this.updateModel();
		if (this.getPreviousPage() == null || this.getPreviousPage().equals("")) {
			return this.getListPage();
		} else {
			return this.getPreviousPage();
		}
	}

	@Override
	protected String getToPageAfterUpdate() {
		page = 1;
		this.updateModel();
		if (this.getPreviousPage() == null || this.getPreviousPage().equals("")) {
			return this.getListPage();
		} else {
			return this.getPreviousPage();
		}
	}

	@Override
	public void resetModel() {
		this.model = null;
		this.model = new Ace();
		this.aceOrder = "";
	}

	@Override
	public void setCriteria(EntityObject criteria) {
		this.criteria = (Ace) criteria;
	}

	@Override
	public void setModel(EntityObject model) {
		this.model = (Ace) model;
	}

	public boolean isAllowPaged() {
		return allowPaged;
	}

	public void setAllowPaged(boolean allowPaged) {
		if (this.allowPaged != allowPaged) {
			entityModelList = null;
			this.allowPaged = allowPaged;
		}
	}

	public boolean isShowParticular() {
		return showParticular;
	}

	public void setShowParticular(boolean showParticular) {
		this.showParticular = showParticular;
	}

	/**
	 * 取得列表数据
	 * 
	 * @param entity
	 *            模板
	 * @return 列表数据
	 */
	@SuppressWarnings("unchecked")
	public ListDataModel getEntityModelList(Template entity) {
		return getEntityModelList(entity, this.allowPaged);
	}

	/**
	 * 取得列表数据
	 * 
	 * @param entity
	 *            时间段


	 * 
	 * @return 列表数据
	 */
	@SuppressWarnings("unchecked")
	public ListDataModel getEntityModelList(TimeRange entity) {
		// if (entityModelList == null){
		this.paramObject = entity;
		this.paramType = "TimeRange";
		adjustPage();
		currentPage = this.aceService.pageQueryByTimeRange(entity, page, pageSize);
		entityModelList = new ListDataModel((List<Ace>) currentPage.getResult());
		// }
		return entityModelList;
	}

	/**
	 * 取得列表数据
	 * 
	 * @param entity
	 *            ACL组


	 * 
	 * @return 列表数据
	 */
	@SuppressWarnings("unchecked")
	public ListDataModel getEntityModelList(AccessGroup entity) {

		return getEntityModelList(entity, this.allowPaged);

	}

	/**
	 * 取得列表数据
	 * 
	 * @param entity
	 *            ACL组


	 * 
	 * @param flag
	 *            分页标识
	 * @return 列表数据
	 */
	@SuppressWarnings("unchecked")
	public ListDataModel getEntityModelList(AccessGroup entity, boolean flag) {
		// if (entityModelList == null){
		this.paramObject = entity;
		this.paramType = "AccessGroup";
		if (flag) {
			adjustPage();
			currentPage = this.aceService.pageQueryByAccessGroup(entity, page, pageSize);
			entityModelList = new ListDataModel((List<Ace>) currentPage.getResult());
			this.aceCount = this.getTotalCount();
		} else {
			List<Ace> aceList = this.aceService.getByAccessGroup(entity);
			entityModelList = new ListDataModel(aceList);
			this.aceCount = aceList.size();
		}
		// }
		return entityModelList;
	}

	/**
	 * 取得列表数据
	 * 
	 * @param entity
	 *            ACL组


	 * 
	 * @param flag
	 *            分页标识
	 * @return 列表数据
	 */
	@SuppressWarnings("unchecked")
	public ListDataModel getEntityModelList(Template entity, boolean flag) {
		// if (entityModelList == null){
		this.paramObject = entity;
		this.paramType = "Template";
		if (flag) {
			adjustPage();
			currentPage = this.aceService.pageQueryByTemplate(entity, page, pageSize);
			entityModelList = new ListDataModel((List<Ace>) currentPage.getResult());
			this.aceCount = this.getTotalCount();
		} else {
			List<Ace> aceList = this.aceService.getByTemplate(entity);
			entityModelList = new ListDataModel(aceList);
			this.aceCount = aceList.size();
		}

		// }
		return entityModelList;
	}

	public String toAddPage(AccessGroup entity, String lastPage) {
		this.sourcePort = null;
		this.desPort = null;
		this.timeRangeName = null;
		String result = super.toAddPage(lastPage);
		this.model.setAccessGroup(entity);
		return result;
	}

	public String toAddPage(Template entity, String lastPage) {
		this.sourcePort = null;
		this.desPort = null;
		this.timeRangeName = null;
		String result = super.toAddPage(lastPage);
		this.model.setTemplate(entity);
		return result;
	}

	@SuppressWarnings("unchecked")
	@Override
	protected void updateModel() {
		this.entityModelList = null;
		if (this.paramObject == null) {
			super.updateModel();
		} else if (this.paramObject instanceof AccessGroup) {
			this.getEntityModelList((AccessGroup) (this.paramObject));
		} else if (this.paramObject instanceof TimeRange) {
			this.getEntityModelList((TimeRange) (this.paramObject));
		} else if (this.paramObject instanceof Template) {
			this.getEntityModelList((Template) (this.paramObject));
		}
	}

	/**
	 * 移动规则顺序
	 * 
	 * @param entity
	 *            规则
	 * @param direction
	 *            方向枚举
	 */
	public void moveAceOrder(Ace entity, MoveDirection direction) {
		aceService.updateAceNumWithDirection(entity, direction);
		this.updateModel();
		this.updateAccessGroupChangeFlag(entity.getAccessGroup());
	}

	/**
	 * 移动规则顺序
	 * 
	 * @param entity
	 *            规则
	 * @param direction
	 *            方向
	 */
	public void moveAceOrder(Ace entity, String direction) {
		MoveDirection md = MoveDirection.valueOf(direction);
		this.moveAceOrder(entity, md);
	}

	@Override
	@SuppressWarnings("unchecked")
	@Transactional
	protected boolean doAdd() {
		// 处理源端口和目的端口
		if (AclUtil.empty(this.model.getSourcePort())) {
			this.model.setSourcePort(this.sourcePort);
		}
		if (AclUtil.empty(this.model.getDesPort())) {
			this.model.setDesPort(this.desPort);
		}
		if (this.paramObject instanceof Template) {
			AclUtil.filterAce(this.model, ((Template) paramObject).getAccessGroupType());
		} else if (this.paramObject instanceof AccessGroup) {
			AclUtil.filterAce(this.model, ((AccessGroup) paramObject).getAclType());
		}
		// 处理时间段名称
		if (this.model.getTimeRange() != null) {
			this.model.setTimeRangeName(this.model.getTimeRange().getName());
		} else {
			this.model.setTimeRangeName(this.timeRangeName);
		}
		// 处理序号
		try {
			this.model.setAceNum(Integer.parseInt(this.getAceOrder()));
		} catch (Exception ex) {
			this.model.setAceNum(0);
		}
		// 已存在则报错
		if (aceService.existByAce(this.model)) {
			throw new BusinessException("acl_ace_error_exist");
		}
		boolean successful = super.doAdd();
		if (successful) {
			this.updateAccessGroupChangeFlag(this.paramObject);
		}
		return successful;
	}

	@Override
	@SuppressWarnings("unchecked")
	@Transactional
	protected boolean doUpdate() {
		// 处理源端口和目的端口
		if (AclUtil.empty(this.model.getSourcePort())) {
			this.model.setSourcePort(this.sourcePort);
		}
		if (AclUtil.empty(this.model.getDesPort())) {
			this.model.setDesPort(this.desPort);
		}
		boolean successful = true;
		boolean beSameRemark = true;
		if (this.paramObject instanceof Template) {
			AclUtil.filterAce(this.model, ((Template) paramObject).getAccessGroupType());
		} else if (this.paramObject instanceof AccessGroup) {
			AclUtil.filterAce(this.model, ((AccessGroup) paramObject).getAclType());
		}
		// 处理时间段名称
		if (this.model.getTimeRange() != null) {
			this.model.setTimeRangeName(this.model.getTimeRange().getName());
		} else {
			this.model.setTimeRangeName(this.timeRangeName);
		}
		Ace tempAce = aceService.get(this.model.getId());
		// 判断是否进行了修改，未修改则不保存，修改则进行保存操作
		if (tempAce != null && tempAce.equals(this.model)) {
			String modelAceRemark = this.model.getRemark() == null ? "" : this.model.getRemark();
			String tempAceRemark = tempAce.getRemark() == null ? "" : tempAce.getRemark();
			if (modelAceRemark.equals(tempAceRemark)) {
				return true;
			} else {
				beSameRemark = false;
			}
		} else {
			// 是否存在相同的
			if (aceService.existByAce(this.model)) {
				throw new BusinessException("acl_ace_error_exist");
			}
		}
		tempAce = this.model.cloneAce(tempAce);
		this.model = tempAce;
		successful = super.doUpdate();
		if (successful && beSameRemark) {
			this.updateAccessGroupChangeFlag(this.paramObject);
		}
		return successful;
	}

	/**
	 * <p>
	 * Description: 删除单个实体操作
	 * </p>
	 * <p>
	 * Create Time: 2009-09-18
	 * </p>
	 * 
	 * @param entity
	 *            要删除的对象
	 */
	@SuppressWarnings("unchecked")
	@Transactional
	public void delete(Ace entity) {
		AccessGroup tempAg = entity.getAccessGroup();
		super.delete(entity);
		this.updateAccessGroupChangeFlag(tempAg);
	}

	/**
	 * 更新ACL组修改标志位
	 * 
	 * @param entity
	 *            ACL组


	 */
	public void updateAccessGroupChangeFlag(EntityObject entity) {
		// 若为ACL组,且该ACL组被设备关联,且changeFlag为false时,将changeFlag改为true
		if (entity != null && entity instanceof AccessGroup) {
			AccessGroup tempAg = (AccessGroup) entity;
			tempAg = accessGroupService.get(tempAg.getId());
			if (deviceAccessGroupService.existByAccessGroup(tempAg)) {
				accessGroupService.refresh(tempAg);
				if (!tempAg.getIsChanged()) {
					tempAg.setIsChanged(true);
					accessGroupService.update(tempAg);
					deviceAccessGroupService.updateChangedByAccessGroup(tempAg);
					accessGroupAction.setModel(tempAg);
				}
			}
		}
	}

	public Integer getAceCount() {
		return aceCount;
	}

	public void setAceCount(Integer aceCount) {
		this.aceCount = aceCount;
	}

	public String toUpdatePage(EntityObject editModel, String previousPage) {
		this.sourcePort = null;
		this.desPort = null;
		this.timeRangeName = null;
		if (editModel != null) {
			Ace tempModel = (Ace) editModel;
			this.timeRangeName = tempModel.getTimeRangeName();
			this.sourcePort = this.getPortString(tempModel.getSourcePort());
			this.desPort = this.getPortString(tempModel.getDesPort());
		}
		return super.toUpdatePage(editModel, previousPage);
	}

	public void changeTimeRangeName() {
		if (this.model != null) {
			if (this.model.getTimeRange() != null) {
				this.timeRangeName = this.model.getTimeRange().getName();
			} else {
				this.timeRangeName = "";
			}
		}
	}

	public List<SelectItem> getPoryTypeItems() {
		List<SelectItem> resultList = new ArrayList<SelectItem>();
		if (this.model != null && !AclUtil.empty(this.model.getProtocolType()) 
				&& (ProtocolTypeEnum.tcp.toString().equals(this.model.getProtocolType()) 
						|| ProtocolTypeEnum.udp.toString().equals(this.model.getProtocolType()))){
			List<PortTypeEnum> portTypeEnumList = PortTypeEnum.getEnumList(this.model.getProtocolType());
			for (PortTypeEnum protTypeEnum : portTypeEnumList) {
				resultList.add(new SelectItem(protTypeEnum.value()));
			}
		}
		return resultList;
	}
	
	public void resetPort(){
		if (this.model != null){
			this.model.setSourcePort(null);
			this.model.setDesPort(null);
		}
		this.sourcePort = null;
		this.desPort = null;
	}

	public String getPortString(String port) {
		if (AclUtil.empty(port)) {
			return "";
		}
		port = port.trim();
		try {
			Integer.parseInt(port);
			return port;
		} catch (Exception ex) {
			String portValue = PortTypeEnum.getEnumValue(port);
			if (portValue == null){
				portValue = port;
			}
			return portValue;
		}
	}

	public void changeSourcePort() {
		if (!AclUtil.empty(this.model.getSourcePort())) {
			this.sourcePort = PortTypeEnum.getEnumValue(this.model.getSourcePort());
		} else {
			this.sourcePort = "";
		}
	}

	public void changeDesPort() {
		if (!AclUtil.empty(this.model.getDesPort())) {
			this.desPort = PortTypeEnum.getEnumValue(this.model.getDesPort());
		} else {
			this.desPort = "";
		}
	}
}
